
/*初赛最好版本
CodeCraft-2021.zip
	
1422003600
	
149725
	
44.706
	
已结束
	
2021-03-27 17:06:19 
*/

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("inline")
#include <iostream>
#include <unordered_map>
#include <map>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <set>
#include <ctime>
using namespace std;

struct Server{
    int id;  // 服务器编号
    string type;  // 服务器型号
    int cpu;  // 总的cpu
    int mem;  // 总的内存
    int cpu_A, cpu_B;  // A B 节点cpu剩余量
    int mem_A, mem_B;  // A B 节点内存剩余量
    int hardware_cost;  // 硬件花费
    int day_cost;  // 每日能耗花费
    unordered_set<int> vms_id;  // 存放部署在该服务器上的虚拟机id
};

struct VM{
    int id;  // 虚拟机ID
    string type;  // 虚拟机型号
    int cpu;
    int mem;
    bool isTwoNodes;  // 是否双节点部署
    int serverID;  // 该虚拟机所部署服务器的ID
    int assign_node;  // 该虚拟机安装在服务器的A节点则为1，B节点则为2
    string s; // 记录每个虚拟机的答案
};


class VmManager{
public:
    int num;  // 当前存活的虚拟机数目
    unordered_map<string, VM> type2VM;  // 建立类型到虚拟机的索引
    unordered_map<int, VM> ID2VM;  // 建立ID到虚拟机的索引
    int getMigrationNum();  // 获取可以的迁移次数
};

int VmManager::getMigrationNum() {
    int cnt = num / 200;
    return cnt;
}

struct Query{
    string type;  // 请求类型：add 或 del
    string vm_type;  // 创建时虚拟机类型
    int vm_id;  // 虚拟机ID
};

vector<vector<Query>> query;  // 处理每天的请求

class ServerManager{
public:
    vector<Server> servers;  // 存放所有的服务器
    vector<Server> ID2Server;  // 建立ID到服务器的索引
    unordered_map<string, Server> type2Server;  // 建立类型到服务器的索引
    unordered_map<string, int> num;  // 存放当前每种类型的服务器数目
    set<string> serverHash;  // 存放当前买了哪些类型的
    int serverID = -1;  // 建立服务器ID，每次新增服务器则此ID加1
    bool isEmpty(Server &server);  // 查看当前服务器是否为空
    long long getEnergyCost();  // 计算当前开机的服务器一天的能耗
    long long getHardwareCost();  // 计算当前买服务器的花费
};

// 方法申明区
vector<Query> reorderQuery(vector<Query> &vector);
bool query_cmp(const Query &q1, const Query &q2);
bool tryAssign(VM &vm);
bool tryAssignForMigration(VM &vm);
bool canAssign(Server &server, VM &vm, int node);
int getFitness(Server &server, VM &vm, int node);
void doAssign(Server &server, VM &vm, int node);
void undoAssign(Server &server, VM &vm, int node);
void delVm(VM &vm);
string chooseBestServer(VM &vm);
vector<string> migration();
Server chooseBestRatio(vector<Server> vector);

int getIndex(int cpu, int mem);

ServerManager serverManager;
VmManager vmManager;

int minR = INT32_MAX, maxR = 0;


/* 多分类
 * cpu/mem
 */
int getIndex(int cpu, int mem)
{
    float ratio = 1.0*cpu/mem;
    if(ratio < 0.89){
        return 0;
    }else{
        return 2;
    }
//    if(ratio < 0.2){
//        return 0;
//    }else if(ratio < 0.6){
//        return 1;
//    }else if(ratio < 1.0){
//        return 2;
//    }else if(ratio < 1.6){
//        return 3;
//    }else{
//        return 4;
//    }

//    if(ratio < 0.18){
//        return 0;
//    }else if(ratio < 0.36){
//        return 1;
//    }else if(ratio < 0.7){
//        return 2;
//    }else if(ratio < 0.9){
//        return 3;
//    }else if(ratio < 1.1){
//        return 4;
//    }else if(ratio < 1.3){
//        return 5;
//    }else if(ratio < 2){
//        return 6;
//    }else{
//        return 7;
//    }
}

void read_data()
{
    int tot_cpu = 0, tot_mem = 0;
    // 读取服务器数据
    int N; cin >> N;

    for(int i = 0; i < N; i ++ ){
        Server server;
        string type; cin >> type;
        type = type.substr(1), type.pop_back();  // 去除行首括号和多余的逗号
        server.type = type;

        string cpu; cin >> cpu;
        cpu.pop_back();
        server.cpu = stoi(cpu);
        server.cpu_A = server.cpu / 2;
        server.cpu_B = server.cpu / 2;

        string mem; cin >> mem;
        mem.pop_back();
        server.mem = stoi(mem);
        server.mem_A = server.mem / 2;
        server.mem_B = server.mem / 2;

        string cost; cin >> cost;
        cost.pop_back();
        server.hardware_cost = stoi(cost);

        cin >> cost;
        cost.pop_back();
        server.day_cost = stoi(cost);
        server.vms_id.clear();
        serverManager.type2Server[server.type] = server;
        serverManager.servers.push_back(server);
    }

    // 读取虚拟机数据
    int M; cin >> M;
    for(int i = 0; i < M; i ++ ){
        VM vm;
        string type; cin >> type;
        type = type.substr(1), type.pop_back();
        vm.type = type;

        string cpu; cin >> cpu;
        cpu.pop_back();
        vm.cpu = stoi(cpu);

        string mem; cin >> mem;
        mem.pop_back();
        vm.mem = stoi(mem);

        string flag; cin >> flag;
        flag.pop_back();
        vm.isTwoNodes = stoi(flag);
        if(vm.isTwoNodes){
            vm.cpu /= 2;
            vm.mem /= 2;
        }
        vm.serverID = -2;
        vmManager.type2VM[vm.type] = vm;
    }

    // 处理请求数据
    int T; cin >> T;
    for(int i = 1; i <= T; i ++ ){
        vector<Query> dayQuery;  // 存放一天的请求
        int R; cin >> R;
        minR = min(minR, R);
        maxR = max(maxR, R);
        for(int j = 0; j < R; j ++ ){
            Query q;
            string type; cin >> type;
            type = type.substr(1), type.pop_back();
            q.type = type;

            if(q.type == "add"){
                string vm_type; cin >> vm_type;
                vm_type.pop_back();
                q.vm_type = vm_type;
            }

            string id; cin >> id;
            id.pop_back();
            q.vm_id = stoi(id);
            if(q.type == "add"){
                VM &vm = vmManager.type2VM[q.vm_type];
                tot_cpu += vm.cpu;
                tot_mem += vm.mem;
                vm.id = q.vm_id;
                vmManager.ID2VM[q.vm_id] = vm;
            }
            dayQuery.push_back(q);
        }
        query.push_back(dayQuery);
    }
}
int g_cpu = 0, g_mem = 0;
int main() {
    clock_t begin = clock();
    ios::sync_with_stdio(false);
//    freopen("../training-1.txt", "r", stdin);
    long long hardware_cost = 0, day_cost = 0;
    // 读取数据
    read_data();
    // 处理每天的请求
    int processedNum = 0;

    for(auto &dayQuery: query) {
        day_cost += serverManager.getEnergyCost();
        // 处理迁移
        vector<string> mig = migration();
        vector<Query> temp = reorderQuery(dayQuery);  // 重新排序今天的请求
        // 存放当天请求的答案
        vector<string> res;
        int last = serverManager.serverID;
        for(auto &q: temp){
            VM &vm = vmManager.ID2VM[q.vm_id];
            if(q.type == "add"){
                g_cpu += vm.cpu, g_mem += vm.mem;
                vmManager.num ++ ;
                // 从现在已有的服务器中看能否部署此虚拟机，如果能则挑一个最适合的服务器来部署
                bool f = tryAssign(vm);
                // 如果不能部署，则新买一个服务器部署
                if(!f){
                    // 从若干种服务器类型中选出一种来部署
                    serverManager.serverID ++ ;
                    string serverType = chooseBestServer(vm);
                    serverManager.serverHash.insert(serverType);
                    // 要购买的服务器
                    Server server = serverManager.type2Server[serverType];
                    server.id = serverManager.serverID;
                    if(vm.isTwoNodes) doAssign(server, vm, 0);
                    else doAssign(server, vm, 1);  // 单节点部署默认放在A节点
                    serverManager.ID2Server.push_back(server);
                    serverManager.num[serverType] ++ ;
                }
            }else if(q.type == "del"){
                vmManager.num -- ;
                delVm(vm);  // 删除此虚拟机
                g_cpu -= vm.cpu, g_mem -= vm.mem;
            }
            processedNum ++ ;
        }
        map<string, vector<Server>> mp;  // 记录每种服务器及其数目
        for(int id = last + 1; id <= serverManager.serverID; id ++ ){
            Server &server = serverManager.ID2Server[id];
            mp[server.type].push_back(server);
        }
        serverManager.serverID = last;
        for(auto &it: mp){
            for(auto &server: it.second){
                serverManager.serverID ++ ;
                int id = serverManager.serverID;
                server.id = id;
                for(auto &vm_id: server.vms_id){
                    VM &vm = vmManager.ID2VM[vm_id];
                    vm.serverID = id;
                }
                serverManager.ID2Server[id] = server;
            }
        }
        cout << "(purchase, " << mp.size() << ")" << endl;
        for(auto &it: mp) cout << "(" << it.first << ", " << it.second.size() << ")" << endl;
        cout << "(migration, " << mig.size() << ")" << endl;
        for(string &s: mig) cout << s << endl;
        for(auto &q: dayQuery){
            VM &vm = vmManager.ID2VM[q.vm_id];
            if(q.type == "add") {
                string s = to_string(vm.serverID);
                if(vm.assign_node == 1) s += ", A";
                if(vm.assign_node == 2) s += ", B";
                cout << "(" << s << ")" << endl;
            }
        }
//        cout << g_cpu << " " << g_mem << " " << 1.0 * g_cpu / g_mem << endl;
    }
    hardware_cost += serverManager.getHardwareCost();
    day_cost += serverManager.getEnergyCost();
//    cout << "hardware_cost: " << hardware_cost << ", energy_cost: " << day_cost << endl;
//    cout << "total cost: " << hardware_cost + day_cost << endl;
//    clock_t end = clock();
//    cout << "cost time: " << end - begin << "ms" << endl;
    return 0;
}
bool cmp2(int a, int b){  // 按照占用cpu+mem小从小到大排序
    auto &t1 = serverManager.ID2Server[a], &t2 = serverManager.ID2Server[b];
    return 1.0 * (t1.cpu_A + t1.cpu_B) / t1.cpu + 1.0 * (t1.mem_A + t1.mem_B) / t1.mem >
           1.0 * (t2.cpu_A + t2.cpu_B) / t2.cpu + 1.0 * (t2.mem_A + t2.mem_B) / t2.mem;
    return t1.cpu - t1.cpu_A - t1.cpu_B + t1.mem - t1.mem_A - t1.mem_B <
           t2.cpu - t2.cpu_A - t2.cpu_B + t2.mem - t2.mem_A - t2.mem_B;
}

bool vm_cmp(const int a, const int b){
    VM &vm1 = vmManager.ID2VM[a], &vm2 = vmManager.ID2VM[b];
    if(vm1.isTwoNodes != vm2.isTwoNodes) return vm1.isTwoNodes < vm2.isTwoNodes;
    return vm1.cpu + vm1.mem > vm2.cpu + vm2.mem;
}

vector<string> migration() {
    vector<string> res;  // 存放每次转移的信息
    int sz = vmManager.getMigrationNum();  // 可迁移次数
    vector<int> temp;  // 从小到大存放拥有虚拟机数目的服务器ID
    for(int i = 0; i <= serverManager.serverID; i ++ ) temp.push_back(i);
    sort(temp.begin(), temp.end(), cmp2);
    for(int i = 0; i < temp.size(); i ++ ){
        int id = temp[i];
        auto &server = serverManager.ID2Server[id];
        vector<int> vmsId;
        for(auto &vmId: server.vms_id){
            vmsId.push_back(vmId);
        }
        sort(vmsId.begin(), vmsId.end(), vm_cmp);
        for(int vmId: vmsId){
            VM &vm = vmManager.ID2VM[vmId];
            int a = vm.serverID, b = vm.assign_node;
            if(sz <= 0) return res;
            undoAssign(server, vm, b);
            bool f = tryAssignForMigration(vm);
            if(f){
                if(a == vm.serverID && b == vm.assign_node) continue;  // 未迁移
                string s = to_string(vm.id) + ", " + to_string(vm.serverID);
                if(vm.assign_node == 1) s += ", A";
                if(vm.assign_node == 2) s += ", B";
                res.push_back("(" + s + ")");
                sz -- ;
            }else{
                doAssign(server, vm, b);
            }
        }
    }
    return res;
}

void delVm(VM &vm) {
    Server &server = serverManager.ID2Server[vm.serverID];
    server.vms_id.erase(vm.id);
    if(vm.isTwoNodes){
        server.cpu_A += vm.cpu, server.mem_A += vm.mem;
        server.cpu_B += vm.cpu, server.mem_B += vm.mem;
    }else{
        if(vm.assign_node == 1){
            server.cpu_A += vm.cpu, server.mem_A += vm.mem;
        }else{
            server.cpu_B += vm.cpu, server.mem_B += vm.mem;
        }
    }
}

bool cmp(const Server &s1, const Server &s2){  // 性价比比较
    return s1.hardware_cost < s2.hardware_cost;
}
string chooseBestServer(VM &vm) {
    int vm_index = getIndex(vm.cpu, vm.mem);     // 计算虚拟机的分类
    vector<Server> temp;
    int d = 3;
    for(auto server: serverManager.servers){
        int server_index = getIndex(server.cpu, server.mem);  // 计算服务器的分类
        if(server_index != vm_index) continue;      // 只购买和本虚拟机分类相同的服务器类型
        if(server.cpu_A <= vm.cpu + d || server.mem_A <= vm.mem + d) continue;
        temp.push_back(server);
    }

    if(temp.size() == 0){
        for(auto server: serverManager.servers){
            int server_index = getIndex(server.cpu, server.mem);  // 计算服务器的分类
            if(server_index != vm_index) continue;
            if(server.cpu_A < vm.cpu || server.mem_A < vm.mem) continue;
            temp.push_back(server);
        }
    }
    sort(temp.begin(), temp.end(), cmp);
//    while(temp.size() >= 3) temp.pop_back();
//    Server ret = chooseBestRatio(temp);  // 挑选出与当前所有虚拟机sum(cpu)/sum(mem)最合适的服务器
    Server ret = temp[0];
    return ret.type;
}

bool rationCmp(const Server &s1, const Server &s2){
    double d1 = 1.0 * g_cpu / g_mem - 1.0 * s1.cpu / s1.mem;
    if(d1 < 0) d1 = -d1;
    double d2 = 1.0 * g_cpu / g_mem - 1.0 * s2.cpu / s2.mem;
    if(d1 < 0) d2 = -d2;
    return d1 < d2;
}
Server chooseBestRatio(vector<Server> temp) {
    sort(temp.begin(), temp.end(), rationCmp);
    return temp[0];
}

bool tryAssignForMigration(VM &vm) {
    int vm_index = getIndex(vm.cpu, vm.mem);    // 计算虚拟机的分类
    int resFitness = INT32_MIN, resID = -1, resNode = -1;
    for(int id = 0; id <= serverManager.serverID; id ++ ){
        Server &server = serverManager.ID2Server[id];
        int server_index = getIndex(server.cpu, server.mem);        // 计算服务器的分类
//        if(server_index != vm_index) continue;      // 只能部署到同分类服务器
        if(vm.isTwoNodes) {
            if (canAssign(server, vm, 0)) {  // 判断当前服务器cpu和内存能部署此虚拟机
                int fitness = getFitness(server, vm, 0);
                if(fitness > resFitness){
                    resFitness = fitness;
                    resID = id;
                    resNode = 0;
                }
            }
        }else{
            if(canAssign(server, vm, 1)){
                int fitness = getFitness(server, vm, 1);
                if(fitness > resFitness){
                    resFitness = fitness;
                    resID = id;
                    resNode = 1;
                }
            }else if(canAssign(server, vm, 2)){
                int fitness = getFitness(server, vm, 2);
                if(fitness > resFitness){
                    resFitness = fitness;
                    resID = id;
                    resNode = 2;
                }
            }
        }
    }
    // 如果没有一台服务器能部署此虚拟机则直接返回false
    if(resID == -1) return false;
    // 部署此虚拟机
    Server &server = serverManager.ID2Server[resID];
    doAssign(server, vm, resNode);
    return true;
}

bool tryAssign(VM &vm) {
    // 存放能部署此虚拟机的服务器的信息，每个数组是{服务器id, 虚拟机部署在哪个节点(0:all, 1:A, 2: B)，服务器与该虚拟机的匹配度}
    vector<vector<int>> temp;
    int vm_index = getIndex(vm.cpu, vm.mem);    // 计算虚拟机的分类
    for(int id = 0; id <= serverManager.serverID; id ++ ){
        Server &server = serverManager.ID2Server[id];
        int server_index = getIndex(server.cpu, server.mem);        // 计算服务器的分类
//        if(server_index != vm_index) continue;                  // 只能部署到同分类服务器
        if(vm.isTwoNodes) {
            if (canAssign(server, vm, 0)) {  // 判断当前服务器cpu和内存能部署此虚拟机
                int fitness = getFitness(server, vm, 0);
                temp.push_back(vector<int>{id, 0, fitness});
            }
        }else{
            if(canAssign(server, vm, 1)){
                int fitness = getFitness(server, vm, 1);
                temp.push_back(vector<int>{id, 1, fitness});
            }else if(canAssign(server, vm, 2)){
                int fitness = getFitness(server, vm, 2);
                temp.push_back(vector<int>{id, 2, fitness});
            }
        }
    }

    // 如果没有一台服务器能部署此虚拟机则直接返回false
    if(temp.empty()) return false;

    // 挑选出最匹配的服务器部署此虚拟机
    int d = temp[0][2], id = temp[0][0], node = temp[0][1];
    for(auto &t: temp){
        if(t[2] > d){
            id = t[0];
            node = t[1];
            d = t[2];
        }
    }
    // 部署此虚拟机
    Server &server = serverManager.ID2Server[id];
    doAssign(server, vm, node);
    return true;
}

void doAssign(Server &server, VM &vm, int node) {
    server.vms_id.insert(vm.id);
    vm.serverID = server.id;
    vm.assign_node = node;
    if(node == 0){
        server.cpu_A -= vm.cpu, server.mem_A -= vm.mem;
        server.cpu_B -= vm.cpu, server.mem_B -= vm.mem;
    }else if(node == 1){
        server.cpu_A -= vm.cpu, server.mem_A -= vm.mem;
    }else{
        server.cpu_B -= vm.cpu, server.mem_B -= vm.mem;
    }
}
void undoAssign(Server &server, VM &vm, int node) {
    server.vms_id.erase(vm.id);
    if(node == 0){
        server.cpu_A += vm.cpu, server.mem_A += vm.mem;
        server.cpu_B += vm.cpu, server.mem_B += vm.mem;
    }else if(node == 1){
        server.cpu_A += vm.cpu, server.mem_A += vm.mem;
    }else{
        server.cpu_B += vm.cpu, server.mem_B += vm.mem;
    }
}

inline int getFitness(Server &server, VM &vm, int node) {
//    int vm_index = getIndex(vm.cpu, vm.mem);
//    int server_index = getIndex(server.cpu, server.mem);
//    int bias = 3-abs(vm_index - server_index);    // 分类不同则加上不同大小的偏置
    int bias = 1;

    int a = 100, b = 66;

    double d1 = a * (server.cpu_A - vm.cpu) + b * (server.mem_A - vm.mem);
    double d2 = a * (server.cpu_B - vm.cpu) + b * (server.mem_B - vm.mem);
    if(serverManager.isEmpty(server)) {
        d1 += 1000000;
        d2 += 1000000;
    }
    if(node == 0) return (- d1 - d2)*bias;
    else if(node == 1) return (- d1)*bias;
    else return (- d2)*bias;
}


bool canAssign(Server &server, VM &vm, int node) {
    if(node == 0){  // 能否双节点部署
        return server.cpu_A >= vm.cpu && server.mem_A >= vm.mem
               && server.cpu_B >= vm.cpu && server.mem_B >= vm.mem;
    }else if(node == 1){  // 能否部署在A节点
        return server.cpu_A >= vm.cpu && server.mem_A >= vm.mem;
    }else{  // 能否部署在B节点
        return server.cpu_B >= vm.cpu && server.mem_B >= vm.mem;
    }
}

vector<Query> reorderQuery(vector<Query> &dayQuery) {
    vector<vector<Query>> list;
    vector<Query> temp;
    for(auto &q: dayQuery){
        if(!temp.empty() && q.type != temp.back().type){
            list.push_back(temp);
            temp.clear();
        }
        temp.push_back(q);
    }
    if(!temp.empty()) list.push_back(temp);
    // 对list中每个部分重排序
    for(auto &item: list){
        if(item.back().type == "del") continue;
        sort(item.begin(), item.end(), query_cmp);
    }

    temp.clear();
    for(auto &item: list){
        for(auto &q: item){
            temp.push_back(q);
        }
    }
    return temp;
}
bool query_cmp(const Query &q1, const Query &q2){
    VM &v1 = vmManager.ID2VM[q1.vm_id], &v2 = vmManager.ID2VM[q2.vm_id];
    if(v1.isTwoNodes != v2.isTwoNodes) return v1.isTwoNodes > v2.isTwoNodes;
    int t1 = v1.cpu + v1.mem;
    int t2 = v2.cpu + v2.mem;
    return t1 > t2;
}
bool ServerManager::isEmpty(Server &server) {
    if(server.cpu_A + server.cpu_B == server.cpu && server.mem_A + server.mem_B == server.mem){
        return true;
    }
    return false;
}

long long ServerManager::getEnergyCost() {
    long long cost = 0;
    for(auto &it: ID2Server){
        auto &server = it;
        if(!isEmpty(server)) cost += server.day_cost;
    }
    return cost;
}

long long ServerManager::getHardwareCost() {
    long long cost = 0;
    for(auto &it: ID2Server){
        auto &server = it;
        cost += server.hardware_cost;
    }
    return cost;
}

/*
 hardware_cost: 360061098, energy_cost: 236983768
total cost: 597044866
 hardware_cost: 323648759, energy_cost: 168802684
total cost: 492451443 = 1089496309

 迁移的时候服务器按照每日能耗从大到小排序：无用
 迁移次数越多结果越好，而且效果很显著
 对数据集重排序是有用的
 getFitness函数使用差值是最合适的(也就是当前使用的这版)


 getfitness函数中设置cpu权重和mem权重比为2：1，在训练数据上可以减少300w
 hardware_cost: 359749837, energy_cost: 236605238
total cost: 596355075
 hardware_cost: 321998551, energy_cost: 168022593
total cost: 490021144 = 1086376219

 hardware_cost: 358143553, energy_cost: 236317086
total cost: 594460639
 hardware_cost: 323399584, energy_cost: 168014251
total cost: 491413835 = 1085874474


hardware_cost: 356270940, energy_cost: 236192716
total cost: 592463656
hardware_cost: 322856075, energy_cost: 166763811
total cost: 489619886 = 1082083542


 hardware_cost: 355837088, energy_cost: 235597617
total cost: 591434705

 hardware_cost: 355627963, energy_cost: 234693752
total cost: 590321715
 hardware_cost: 321217735, energy_cost: 165239852
total cost: 486457587 = 1076779302


————————————————————————————————————————————————————————————————————
 5分类+购买、部署、迁移都只能在本分类中进行
hardware_cost: 384555134, energy_cost: 254154698
total cost: 638709832
cost time: 61410ms
hardware_cost: 342106597, energy_cost: 178183753
total cost: 520290350
cost time: 31366ms

 8分类+购买、部署、迁移都只能在本分类中进行
hardware_cost: 376755906, energy_cost: 249199691
total cost: 625955597
cost time: 98204ms
 hardware_cost: 341001726, energy_cost: 177722922
total cost: 518724648
cost time: 42055ms

 8分类 + 购买、部署时只允许部署到本类别，迁移时允许任意迁移
 hardware_cost: 364094140, energy_cost: 239799247
total cost: 603893387
cost time: 8943ms
hardware_cost: 343163863, energy_cost: 170927039
total cost: 514090902
cost time: 13193ms

8分类 + 部署时允许部署到任意类别，购买、迁移时只允许在本类别
hardware_cost: 361787648, energy_cost: 239613314
total cost: 601400962
cost time: 44271ms
 hardware_cost: 339767187, energy_cost: 173291238
total cost: 513058425
cost time: 26230ms

 8分类+购买本类
hardware_cost: 357783504, energy_cost: 237542571
total cost: 595326075
cost time: 5613ms
hardware_cost: 351877864, energy_cost: 171140276
total cost: 523018140
cost time: 17855ms

 2分类+购买、部署、迁移都只在本分类中进行
hardware_cost: 420993723, energy_cost: 278183491
total cost: 699177214
cost time: 114831ms
hardware_cost: 392641999, energy_cost: 195659644
total cost: 588301643
cost time: 53708ms

 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 2分类+只是购买时在本分类 0.88为分界线
hardware_cost: 354426454, energy_cost: 234018959
total cost: 588445413
cost time: 6211ms
 hardware_cost: 323260874, energy_cost: 165744850
total cost: 489005724
cost time: 24272ms

 588445413+489005724 = 1 077 451 137


 #####################二分类 只在购买的时候分类
 0.75
 hardware_cost: 355027014, energy_cost: 234348811
total cost: 589375825
cost time: 7613ms
 0.8
 hardware_cost: 354865086, energy_cost: 234259120
total cost: 589124206
cost time: 6241ms
0.85
 hardware_cost: 354657539, energy_cost: 233973241
total cost: 588630780
cost time: 5865ms
  0.88
 hardware_cost: 354426454, energy_cost: 234018959
total cost: 588445413
cost time: 6211ms
 0.89
 hardware_cost: 354846712, energy_cost: 233916043
total cost: 588762755
cost time: 6018ms
 0.9
 hardware_cost: 354503554, energy_cost: 233837495
total cost: 588341049
cost time: 6049ms
0.92
hardware_cost: 354625813, energy_cost: 233972789
total cost: 588598602
cost time: 7380ms
 1.0
 hardware_cost: 355782456, energy_cost: 234618059
total cost: 590400515
cost time: 7958ms

#####################三分类 只在购买的时候分类
0.6 1.2
 hardware_cost: 355348786, energy_cost: 234995089
total cost: 590343875
cost time: 6042ms

0.5 1.5
hardware_cost: 357189014, energy_cost: 236035615
total cost: 593224629
cost time: 6706ms

 */